package main

import (
	"flag"
	"fmt"
	"math"
	"strconv"

	// 复制板
	"github.com/atotto/clipboard"
)

var table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
var tr = map[string]int{}
var s = []int{11, 10, 3, 8, 4, 6}
var xor = 177451812
var add = 8728348608

func init() {
	tableByte := []byte(table)
	for i := 0; i < 58; i++ {
		tr[string(tableByte[i])] = i
	}
}

// bv 转 av，转换函数参考。原始算法作者：mcfx 链接：https://www.zhihu.com/question/381784377/answer/1099438784 编辑于 2020-03-24
func bv2av(bv string) string {
	var r int
	arr := []rune(bv)

	for i := 0; i < 6; i++ {
		r += tr[string(arr[s[i]])] * int(math.Pow(float64(58), float64(i)))
	}
	return strconv.Itoa((r - add) ^ xor)
}

// av 转 bv，转换函数参考。原始算法作者：mcfx 链接：https://www.zhihu.com/question/381784377/answer/1099438784 编辑于 2020-03-24
func av2bv(av int) string {
	x := (av ^ xor) + add
	r := []string{"B", "V", "1", " ", " ", "4", " ", "1", " ", "7", " ", " "}
	for i := 0; i < 6; i++ {
		r[s[i]] = string(table[int(math.Floor(float64(x/int(math.Pow(float64(58), float64(i))))))%58])
	}
	var result string
	for i := 0; i < 12; i++ {
		result += r[i]
	}
	return result
}

func main() {
	// 定义接收需要转换的模式，可选内容为 av 或者 bv
	var changeModule string
	// 定义接收的需要转换的 av 或者 bv 号
	var dataString string

	// StringVar 用指定的名称、控制台参数项目、默认值、使用信息注册一个 string 类型 flag，并将 flag 的值保存到 p 指向的变量
	flag.StringVar(&changeModule, "m", "bv", "转换模式，默认 bv 转换 av")
	flag.StringVar(&dataString, "d", "BV1kU4y157Cv", "需要转换的数据，默认 BV1kU4y157Cv")
	// 从 arguments 中解析注册的 flag。必须在所有 flag 都注册好而未访问其值时执行。未注册却使用 flag -help 时，会返回 ErrHelp
	flag.Parse()

	/*
		判断模式为 av || bv
		av：av 号转换为 bv 号
		bv：bv 号转换为 av 号
	*/
	if changeModule == "av" {
		// dataString 数据类型为字符串类型，但是函数接收值为 int 型，进行转换
		dataInt, err := strconv.Atoi(dataString)
		if err != nil {
			fmt.Println(err)
		}

		fmt.Printf("转换模式为 AV 转 BV 号，转换前 AV 码为：%v, 转换后 BV 码为：%v , 内容已复制进粘贴板直接 Ctrl + v 即可 ！！！\n", dataString, av2bv(dataInt))
		//复制内容到剪贴板
		clipboard.WriteAll(av2bv(dataInt))

	} else {
		fmt.Printf("转换模式为 BV 转 AV 号，转换前 BV 码为：%v, 转换后 AV 码为：%v , 内容已复制进粘贴板直接 Ctrl + v 即可 ！！！\n", dataString, bv2av(dataString))
		//复制内容到剪贴板
		clipboard.WriteAll(bv2av(dataString))
	}
}
